package com.xyzwps.server.paimon.ui

import com.xyzwps.server.paimon.app.ContextUser
import com.xyzwps.server.paimon.common.ReqCtx
import com.xyzwps.server.paimon.common.TokenGetter
import com.xyzwps.server.paimon.model.service.UserDomainService
import com.xyzwps.server.paimon.model.service.UserSessionDomainService
import org.jetbrains.exposed.v1.jdbc.transactions.transaction
import org.springframework.graphql.server.WebGraphQlInterceptor
import org.springframework.graphql.server.WebGraphQlRequest
import org.springframework.graphql.server.WebGraphQlResponse
import org.springframework.stereotype.Component
import reactor.core.publisher.Mono

@Component
class GraphQlAuthInterceptor(
    private val sessionService: UserSessionDomainService,
    private val userDomainService: UserDomainService
) : WebGraphQlInterceptor {

    override fun intercept(request: WebGraphQlRequest, chain: WebGraphQlInterceptor.Chain): Mono<WebGraphQlResponse> {
        val token = TokenGetter(request).token
        token?.let {
            transaction {
                sessionService.getSession(it)?.let { session ->
                    userDomainService.getById(session.userId)?.let { user ->
                        val context: Map<String, Any> = mapOf(
                            ReqCtx.USER to ContextUser(user),
                            ReqCtx.SESSION to session,
                            ReqCtx.TOKEN to it
                        )
                        request.configureExecutionInput { executionInput, builder ->
                            builder.graphQLContext(context).build()
                        }
                    }
                }
            }
        }

        return chain.next(request)
    }
}
